package com.example.design_mode;

import java.util.Arrays;
import java.util.LinkedList;
import java.util.Stack;

public class Singleton_mode {
    private static volatile Singleton_mode instance;

    //构造器私有化
    private Singleton_mode(){}
    //饿汉方式：指全局的单例实例在类装载时构建。即这个单例没有用到也会被创建，会占用内存；但优点是构建时不用考虑并发问题
    //懒汉方式：指全局的单例实例在第一次被使用时构建。优点是节省内存，缺点是需要控制并发下，只能有一个线程创建成功

    //这里只演示懒汉模式

    /**
     * 解答二次检验null值
     *
     * 假如两个线程A、B几乎同时到达第一层 if (instance == null)，并且都通过了第一层检验
     * 然后两个线程就会依次执行同步代码块，若没有第二层判断，就会分别创建了一个单例对象
     * 这就违反了单例全局唯一实例的特性
     *
     * @return
     */
    public static Singleton_mode getInstance() {
        if (instance == null) {
            synchronized (Singleton_mode.class) {
                //外层已经判断多了，为什么在里层还要再判断一次？答案在上面
                if (instance == null) {
                    instance = new Singleton_mode();
                }
            }
        }
        return instance;
    }

    public static void main(String[] args) {
        int[] nums1 = {1,2,3,0,0,0};
        int[] nums2 = {2,5,6};
        merge(nums1,3,nums2, 3);
    }

    public static void merge(int[] nums1, int m, int[] nums2, int n) {
        //初始化一个m+n的新数组
        int[] nums = new int[m+n];

        //初始化两个指针下标,用于记录nums1和nums当前的移动位置
        int nums1Index = 0;
        int nums2Index = 0;
        int j = 0;

        for(int i=0; i < m+n; i++) {

            //判断如果某个数组已遍历至最后一个元素后, 就将另一个数组剩余的值依次插入新数组就可
            if(nums1Index == m) {
                while(nums2Index < n) {
                    nums[j] = nums2[nums2Index];

                    j++;
                    nums2Index++;
                }
                break;
            } else if(nums2Index == n) {
                while(nums1Index < m) {
                    nums[j] = nums1[nums1Index];

                    j++;
                    nums1Index++;
                }
                break;
            }

            int nums1Value = nums1[nums1Index];
            int nums2Value = nums2[nums2Index];

            //将小的放入新数组
            nums[i] = Math.min(nums1Value,nums2Value);

            //比值小的元素所在数组后移一位
            int i1 = nums1Value <= nums2Value ? nums1Index++ : nums2Index++;
            System.out.println(i1);
            j++;
        }

        System.out.println(Arrays.toString(nums));

        //遍历nums将值都赋给nums1
        for(int k = 0; k < nums.length; k++) {
            nums1[k] = nums[k];
        }

        System.out.println(Arrays.toString(nums1));
    }
}
